(function(){

YAHOO.pendular.KeywordDictionary = function(config){
    this.keywords = {};
};

YAHOO.lang.extend(YAHOO.pendular.KeywordDictionary, Object, {
    keywords: {},
    minCount: null,
    maxCount: 0,
    makeKeywords: function(text){
        return text.replace(/[\W_]+/g, " ").split(" ");
    },
    getKeywordIndex: function(keywords){
        var keyword, numKeywords = keywords.length, i, index = {};
        for (i=0; i<numKeywords; i++){
            keyword = keywords[i];
            index[keyword.toUpperCase()] = keyword;
        }
        return index;
    },
    addEntryKeywords: function(entry, keywordsstring){
        entry.keywords = this.getKeywordIndex(
            this.makeKeywords(keywordsstring)
        );
    },
    addEntry: function(entry, keywords){
        var thisKeywords = this.keywords, thisKeywordsEntry,
            minEntry = null;
        if (!keywords) {
            keywords = entry.keywords;
        }
        for (keyword in keywords) {
            if (!keyword.length) {
                continue;
            }
            if (YAHOO.lang.hasOwnProperty(thisKeywords, keyword)){
                thisKeywordsEntry = thisKeywords[keyword];
            }
            else {
                thisKeywordsEntry = thisKeywords[keyword] = {
                    keyword: keywords[keyword],
                    items: {},
                    count: 0
                };
            }
            thisKeywordsEntry.items[entry.key] = entry;
            thisKeywordsEntry.count++;
            if (this.maxCount < thisKeywordsEntry.count) {
                this.maxCount = thisKeywordsEntry.count;
            }
            if (minEntry===null || minEntry.count > thisKeywordsEntry.count){
                minEntry = thisKeywordsEntry;
            }
        }
        this.minCount = minEntry.count;
    },
    eachKeyword: function(callback){
        var key, entries = this.keywords;
        for (key in entries) {
            callback(key, entries[key]);
        }
    },
    updateStats: function(){
        var keywords = this.keywords, keyword, count;
        this.maxCount = 0;
        for (key in keywords) {
            keyword = keywords[key];
            count = keyword.count;
            if (this.minCount > count){
                this.minCount = count;
            }
            if (count > this.maxCount) {
                this.maxCount = count;
            }
        }
    },
    removeKeywords: function(keywords){
        if (YAHOO.lang.isArray(keywords)) {
            var numKeywords = keywords.length, keyword, i,
                entries, key, entry                
            ;
            for (i=0; i<numKeywords; i++) {
                this.removeKeywords(keywords[i]);
            }
        }
        else 
        if (YAHOO.lang.isString(keywords)) {
            delete this.keywords[keywords.toUpperCase()];
        }
        else {
            throw "Invalid argument";
        }
    },
    getKeywordEntries: function(keywords, keywordEntries){
        var collection = {};
        if (YAHOO.lang.isUndefined(keywordEntries)){
            keywordEntries = this.keywords;
        }
        if (YAHOO.lang.isArray(keywords)) {
            var numKeywords = keywords.length, keyword, i,
                entries, key, entry                
            ;            
            for (i=0; i<numKeywords; i++) {
                if (!keywords[i].length) {
                    continue;
                }
                entries = this.getKeywordEntries(
                    keywords[i].toUpperCase(), 
                    keywordEntries
                );
                if (!entries) {
                    return null;
                }

                if (i) {
                    for (key in collection) {
                        if (!YAHOO.lang.hasOwnProperty(entries, key)) {
                            delete collection[key];
                        }
                    }
                }
                else {
                    for (key in entries) {
                        collection[key] = entries[key]
                    }
                }
            }
        }
        else 
        if (YAHOO.lang.isString(keywords)){
            if (!YAHOO.lang.hasOwnProperty(keywordEntries, keywords)) {
                return null;
            }
            YAHOO.lang.augmentObject(collection, keywordEntries[keywords].items);
        }
        else {
            throw "Invalid argument";
        }
        return collection;
    },
    getArray: function(sort) {
        var words = [], word,
            minCount, maxCount = 0
        ;
        this.eachKeyword(function(key, entries){
            var numEntries = entries.count;
            words.push({
                key: key,
                word: entries.keyword,
                count: numEntries
            });
            if (YAHOO.lang.isUndefined(minCount) || numEntries<minCount) {
                minCount = numEntries;
            }
            else
            if (numEntries>maxCount) {
                maxCount = numEntries;
            }
        });
        if (sort) {
            words.sort(function(a, b){
                if (a.key > b.key) {
                    return 1;
                }
                else
                if (a.key < b.key) {
                    return -1
                }
                else {
                    return 0;
                }
            });
        }
        return words;
    }
});

})();
